import json

from django.db import transaction, IntegrityError
from django.db.models import Count, Q
from django_filters.rest_framework import DjangoFilterBackend
from drf_spectacular.utils import extend_schema
from rest_framework import status, filters
from rest_framework.decorators import action
from rest_framework.response import Response

# Create your views here.
from apps.common.models import Pagination
from apps.data.schemas import DownloadResponse, UploadRequest, UploadResponse, UploadPhotoResponse
from apps.opoc.filters import Opoc_InspectionRecordsFilter
from apps.opoc.models import Opoc_InspectionRecord, Opoc_InspectionPhoto, Opoc_InspectionPhoto_temp
from apps.opoc.serializers import Opoc_InspectionRecordsSerializer, Opoc_InspectionPhotosSerializer, \
    Opoc_InspectionPhotosTempSerializer
from extensions.exceptions import ValidationError
from extensions.permissions import IsAuthenticated
from extensions.serializers import BaseSerializer
from extensions.viewsets import *
from apps.opoc.filters import *
from apps.opoc.models import *
from apps.opoc.serializers import *
from apps.system.models import User
from user_agents import parse

import logging

logger = logging.getLogger(__name__)


class Opoc_Records_ListViewSet(ModelViewSet, ExportMixin, ImportMixin):
    """一人一码"""
    pagination_class = Pagination
    permission_classes = [IsAuthenticated]
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    search_fields = ['company__name', 'name', 'sfz_number', 'phone']
    select_related_fields = ['company']
    ordering_fields = ['id', 'name','add_time']

    def get_client_type(self):
        user_agent = self.request.META.get('HTTP_USER_AGENT', '')
        user_agent = parse(user_agent)
        return 'mobile' if user_agent.is_mobile else 'desktop'

    def get_serializer_class(self):
        # 获取用户代理
        client_type = self.get_client_type()
        # 根据用户代理返回不同的序列化器
        if client_type == 'mobile':
            return MobileOpoc_Records_ListSerializer  # 手机端使用的序列化器
        else:
            return DesktopOpoc_Records_ListSerializer  # 电脑端使用的序列化器

    def get_queryset(self):
        # 获取查询参数
        inspectionrecord_params = self.request.query_params.get('inspectionrecord_params', None)
        # 获取用户代理
        client_type = self.get_client_type()
        # 构建基本查询条件
        base_query = Q(del_flag=False)
        # 根据权限添加额外的查询条件
        if "opoc_view_all" not in self.request.user.permissions:
            base_query &= Q(company=self.request.user.company)
        # 根据用户代理返回不同的查询结果
        if client_type == 'mobile':
            # 手机端使用的查询结果
            queryset = Opoc_Records.objects.filter(base_query).annotate(
            # inspectionrecord_count=Count('Opoc_InspectionRecord')).values('id','company__name', 'name', 'sfz_number', 'phone','slug','inspectionrecord_count')
            inspectionrecord_count=Count('Opoc_InspectionRecord')).all()
            filter_class = MobileOpoc_Records_ListFilter
        else:
            # 电脑端使用的查询结果
            queryset = Opoc_Records.objects.filter(base_query).annotate(
            inspectionrecord_count=Count('Opoc_InspectionRecord')).all()
            filter_class = DesktopOpoc_Records_ListFilter
        # 应用inspectionrecord_params过滤器
        if inspectionrecord_params == "1":
            queryset = queryset.filter(inspectionrecord_count=0)
        elif inspectionrecord_params == "2":
            queryset = queryset.filter(inspectionrecord_count__gt=0)
        filtered_queryset = filter_class(self.request.GET, queryset=queryset)
        return filtered_queryset.qs

    @action(detail=False, methods=['get'])
    def get_id(self, request, *args, **kwargs):
        """获取数据id"""
        slug = request.GET.get('slug', None)
        record = Opoc_Records.objects.get(slug=slug)
        return Response(data={'id': record.id}, status=status.HTTP_200_OK)

    @action(detail=False, methods=['get'])
    def waitMeModify(self, request, *args, **kwargs):
        """待我修改"""
        query =Q(filled_by=self.user) & Q(is_effective=-1)
        queryset = Opoc_Records.objects.filter(query)
        result = queryset.aggregate(
            total_count=Count('name')
        )
        return Response(data=result, status=status.HTTP_200_OK)

    @action(detail=False, methods=['get'])
    def waitMeCheck(self, request, *args, **kwargs):
        """待我审核"""
        query =Q(next_checker=self.user) & Q(is_effective=0)
        queryset = Opoc_Records.objects.filter(query)
        result = queryset.aggregate(
            total_count=Count('name')
        )
        return Response(data=result, status=status.HTTP_200_OK)

    @action(detail=False, methods=['post'])
    def delete_selected(self, request):
        """删除所选"""
        selected_ids = request.data['selected_ids']
        # deleted_count = Opoc_Records.objects.filter(id__in=selected_ids,status=-1).update(del_flag=True)
        deleted_count = Opoc_Records.objects.filter(id__in=selected_ids).update(del_flag=True)#在不是离职状态也可以删除
        result={"status": "success", "deleted_count": deleted_count}
        return Response(data=result, status=status.HTTP_200_OK)


    @extend_schema(responses={200: DownloadResponse})
    @action(detail=False, methods=['get'])
    def import_template(self, request, *args, **kwargs):
        """导入模板"""
        return self.get_template_response(Opoc_RecordsImportSerializer,"新系统一人一码导入模板")

    @extend_schema(request=UploadRequest, responses={200: UploadResponse})
    @action(detail=False, methods=['post'])
    @transaction.atomic
    def import_data(self, request, *args, **kwargs):
        """导入数据"""
        request_serializer = UploadRequest(data=request.data)
        request_serializer.is_valid(raise_exception=True)
        validated_data = request_serializer.validated_data
        import_serializer = self.load_data(validated_data['file'], Opoc_RecordsImportSerializer)
        import_serializer.is_valid(raise_exception=True)
        Opoc_items = import_serializer.validated_data
        # Opoc_set = Opoc_Records.objects.all()
        update_count = 0
        create_count = 0
        del_flag_changed_count = 0  # Add a new counter variable
        for Opoc_item in Opoc_items:
            # labor_service_units = Opoc_item.pop('labor_service_unit', [])
            service_order_pdfs = Opoc_item.pop('service_order_pdf', [])
            task_dispatch_pdfs = Opoc_item.pop('task_dispatch_pdf', [])
            pdf_items = ['construction_contract_pdf', 'insurance_pdf', 'safety_responsibility_pdf',
                         'safety_education_pdf',
                         'safety_disclosure_pdf']
            for pdf_item in pdf_items:
                Opoc_item[pdf_item] = self.get_pdfinstance(Opoc_item, pdf_item)

            img_items = ['climb_high_img', 'electrician_img', 'safety_officer_img','other_person_img']
            for img_item in img_items:
                Opoc_item[img_item] = self.get_imginstance(Opoc_item, img_item)
            opoc_record = Opoc_Records.objects.filter(sfz_number=Opoc_item['sfz_number']).first()
            if opoc_record:
                # Update the existing record
                # Check if del_flag is 1 before updating
                if opoc_record.del_flag == 1:
                    del_flag_changed_count += 1
                Opoc_Records.objects.filter(sfz_number=Opoc_item['sfz_number']).update(del_flag=0,**Opoc_item)
                update_count += 1
            else:
                Opoc_item['filled_by'] = self.user
                Opoc_item['company'] = self.user.company
                Opoc_item['id'] = Opoc_Records().generate_unique_id()
                Opoc_item['slug'] = Opoc_Records().generate_slug()
                opoc_record = Opoc_Records.objects.create(**Opoc_item)
                create_count += 1
            # opoc_record.labor_service_unit.set(labor_service_units)
            opoc_record.service_order_pdf.set(service_order_pdfs)
            opoc_record.task_dispatch_pdf.set(task_dispatch_pdfs)

        return Response(status=status.HTTP_200_OK, data={'update_count': update_count,
                                                         'create_count': create_count,
                                                         'del_flag_changed_count': del_flag_changed_count
                                                         })

    def get_pdfinstance(self, Opoc_item, pdf_item):
        if pdf_item in Opoc_item:
            try:
                Opoc_item[pdf_item] = Common_Pdfs.objects.get(id=Opoc_item[pdf_item])
            except Common_Pdfs.DoesNotExist:
                Opoc_item[pdf_item] = None
        else:
            Opoc_item[pdf_item] = None
        return Opoc_item[pdf_item]

    def get_imginstance(self, Opoc_item, img_item):
        if img_item in Opoc_item:
            try:
                Opoc_item[img_item] = Opoc_Certificate_Imgs.objects.get(id=Opoc_item[img_item])
            except Opoc_Certificate_Imgs.DoesNotExist:
                Opoc_item[img_item] = None
        else:
            Opoc_item[img_item] = None
        return Opoc_item[img_item]



class Opoc_RecordsViewSet(ModelViewSet, ExportMixin, ImportMixin):
    """一人一码"""
    queryset = Opoc_Records.objects.all()
    serializer_class = Opoc_RecordsSerializer
    pagination_class = Pagination
    permission_classes = [IsAuthenticated]
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    filter_class = Opoc_RecordsFilter
    search_fields = ['company__name', 'name', 'sfz_number', 'phone']
    select_related_fields = ['company', 'filled_by',
                             'climb_high_img','electrician_img','safety_officer_img','other_person_img',
                             'construction_contract_pdf','insurance_pdf','safety_responsibility_pdf','safety_education_pdf',
                             'safety_disclosure_pdf','service_order_pdf','task_dispatch_pdf','labor_service_unit',
                             ]
    # prefetch_related_fields = ['check_records']
    ordering_fields = ['id', 'name','is_effective','add_time']

    def get_queryset(self):
        certificate_holding = self.request.query_params.get('certificate_holding', None)
        # 构建基本查询条件
        base_query = Q(del_flag=False)
        # 根据权限添加额外的查询条件
        if "opoc_view_all" not in self.request.user.permissions:
            base_query &= Q(company=self.request.user.company)
        # 添加证书持有查询条件（如果存在）
        if certificate_holding:
            certificate_holding_query = Q(certificate_holding__contains=int(certificate_holding))
            base_query &= certificate_holding_query
        queryset = Opoc_Records.objects.filter(base_query)
        return queryset

    # def add_record(self,serializer):
    #     opoc = serializer.save()
    #     opoc_check = OpocCheck.objects.create(
    #         opoc=opoc, check_user=self.user,
    #         opinion=self.request.data['opinion'],
    #         is_agree=self.request.data['is_agree'])
    #     opoc.check_records.add(opoc_check)
    #
    # @transaction.atomic
    # def perform_create(self,serializer):
    #     self.add_record(serializer)
    #
    # @transaction.atomic
    # def perform_update(self, serializer):
    #     self.add_record(serializer)


    @action(detail=False, methods=['get'])
    def get_id(self, request, *args, **kwargs):
        """获取数据id"""
        slug = request.GET.get('slug', None)
        record = Opoc_Records.objects.get(slug=slug)
        return Response(data={'id': record.id}, status=status.HTTP_200_OK)

    @action(detail=False, methods=['get'])
    def get_sfz_number(self, request, *args, **kwargs):
        """获取数据sfz_number"""
        sfz_number = request.GET.get('sfz_number', None)
        id = request.GET.get('id', None)
        #如果id不为空，说明是修改，需要排除自身
        if id is not None and id != '':
            exists = Opoc_Records.objects.exclude(id=id).filter(sfz_number=sfz_number).exists()
        else:
            exists = Opoc_Records.objects.filter(sfz_number=sfz_number).exists()
        return Response(data={'exists': exists}, status=status.HTTP_200_OK)



    @action(detail=False, methods=['get'])
    def waitMeModify(self, request, *args, **kwargs):
        """待我修改"""
        query =Q(filled_by=self.user) & Q(is_effective=-1)
        queryset = Opoc_Records.objects.filter(query)
        result = queryset.aggregate(
            total_count=Count('name')
        )
        return Response(data=result, status=status.HTTP_200_OK)

    @action(detail=False, methods=['get'])
    def waitMeCheck(self, request, *args, **kwargs):
        """待我审核"""
        query =Q(next_checker=self.user) & Q(is_effective=0)
        queryset = Opoc_Records.objects.filter(query)
        result = queryset.aggregate(
            total_count=Count('name')
        )
        return Response(data=result, status=status.HTTP_200_OK)

    @action(detail=False, methods=['post'])
    def delete_selected(self, request):
        """删除所选"""
        selected_ids = request.data['selected_ids']
        # deleted_count = Opoc_Records.objects.filter(id__in=selected_ids,status=-1).update(del_flag=True)
        deleted_count = Opoc_Records.objects.filter(id__in=selected_ids).update(del_flag=True)#在不是离职状态也可以删除
        result={"status": "success", "deleted_count": deleted_count}
        return Response(data=result, status=status.HTTP_200_OK)


    @extend_schema(responses={200: DownloadResponse})
    @action(detail=False, methods=['get'])
    def import_template(self, request, *args, **kwargs):
        """导入模板"""
        return self.get_template_response(Opoc_RecordsImportSerializer,"新系统一人一码导入模板")

    @extend_schema(request=UploadRequest, responses={200: UploadResponse})
    @action(detail=False, methods=['post'])
    @transaction.atomic
    def import_data(self, request, *args, **kwargs):
        """导入数据"""
        request_serializer = UploadRequest(data=request.data)
        request_serializer.is_valid(raise_exception=True)
        validated_data = request_serializer.validated_data
        import_serializer = self.load_data(validated_data['file'], Opoc_RecordsImportSerializer)
        import_serializer.is_valid(raise_exception=True)
        Opoc_items = import_serializer.validated_data
        # Opoc_set = Opoc_Records.objects.all()
        update_count = 0
        create_count = 0
        del_flag_changed_count = 0  # Add a new counter variable
        for Opoc_item in Opoc_items:
            # labor_service_units = Opoc_item.pop('labor_service_unit', [])
            service_order_pdfs = Opoc_item.pop('service_order_pdf', [])
            task_dispatch_pdfs = Opoc_item.pop('task_dispatch_pdf', [])
            pdf_items = ['construction_contract_pdf', 'insurance_pdf', 'safety_responsibility_pdf',
                         'safety_education_pdf',
                         'safety_disclosure_pdf']
            for pdf_item in pdf_items:
                Opoc_item[pdf_item] = self.get_pdfinstance(Opoc_item, pdf_item)

            img_items = ['climb_high_img', 'electrician_img', 'safety_officer_img','other_person_img']
            for img_item in img_items:
                Opoc_item[img_item] = self.get_imginstance(Opoc_item, img_item)
            opoc_record = Opoc_Records.objects.filter(sfz_number=Opoc_item['sfz_number']).first()
            if opoc_record:
                # Update the existing record
                # Check if del_flag is 1 before updating
                if opoc_record.del_flag == 1:
                    del_flag_changed_count += 1
                Opoc_Records.objects.filter(sfz_number=Opoc_item['sfz_number']).update(del_flag=0,**Opoc_item)
                update_count += 1
            else:
                Opoc_item['filled_by'] = self.user
                Opoc_item['company'] = self.user.company
                Opoc_item['id'] = Opoc_Records().generate_unique_id()
                Opoc_item['slug'] = Opoc_Records().generate_slug()
                opoc_record = Opoc_Records.objects.create(**Opoc_item)
                create_count += 1
            # opoc_record.labor_service_unit.set(labor_service_units)
            opoc_record.service_order_pdf.set(service_order_pdfs)
            opoc_record.task_dispatch_pdf.set(task_dispatch_pdfs)

        return Response(status=status.HTTP_200_OK, data={'update_count': update_count,
                                                         'create_count': create_count,
                                                         'del_flag_changed_count': del_flag_changed_count
                                                         })

    def get_pdfinstance(self, Opoc_item, pdf_item):
        if pdf_item in Opoc_item:
            try:
                Opoc_item[pdf_item] = Common_Pdfs.objects.get(id=Opoc_item[pdf_item])
            except Common_Pdfs.DoesNotExist:
                Opoc_item[pdf_item] = None
        else:
            Opoc_item[pdf_item] = None
        return Opoc_item[pdf_item]

    def get_imginstance(self, Opoc_item, img_item):
        if img_item in Opoc_item:
            try:
                Opoc_item[img_item] = Opoc_Certificate_Imgs.objects.get(id=Opoc_item[img_item])
            except Opoc_Certificate_Imgs.DoesNotExist:
                Opoc_item[img_item] = None
        else:
            Opoc_item[img_item] = None
        return Opoc_item[img_item]


class Opoc_RecordsImageViewSet(ModelViewSet):
    """Opoc个人images"""

    serializer_class = Opoc_Certificate_ImgsSerializer
    pagination_class = Pagination
    permission_classes = [IsAuthenticated]
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    filter_class = Opoc_Certificate_ImgsFilter
    search_fields = ['name']
    select_related_fields = ['filled_by']
    ordering_fields = ['id', 'name', 'add_time']
    queryset = Opoc_Certificate_Imgs.objects.all()

    @transaction.atomic
    def perform_destroy(self, instance):
        instance.file.delete(save=False)
        instance.delete()
        Response(status=status.HTTP_204_NO_CONTENT)


class Opoc_CommonPdfsViewSet(ModelViewSet):
    """Opoc公共pdf"""

    serializer_class = Opoc_Common_PdfsSerializer
    pagination_class = Pagination
    permission_classes = [IsAuthenticated]
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    filter_class = Opoc_Common_PdfsFilter
    search_fields = ['company__name', 'name']
    select_related_fields = ['company', 'filled_by']
    ordering_fields = ['id', 'name', 'add_time']
    queryset = Common_Pdfs.objects.all()

    @transaction.atomic
    def perform_destroy(self, instance):
        instance.file.delete(save=False)
        instance.delete()
        Response(status=status.HTTP_204_NO_CONTENT)


class Opoc_InspectionPhotosViewSet(ModelViewSet):
    """Opoc检查记录图片"""

    serializer_class = Opoc_InspectionPhotosSerializer
    pagination_class = Pagination
    permission_classes = [IsAuthenticated]
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    search_fields = ['company__name', 'name']
    select_related_fields = ['company', 'filled_by']
    ordering_fields = ['id', 'name', 'add_time']
    queryset = Opoc_InspectionPhoto.objects.all()

    @transaction.atomic
    def perform_destroy(self, instance):
        instance.file.delete(save=False)
        instance.delete()
        Response(status=status.HTTP_204_NO_CONTENT)

class Opoc_InspectionPhotosTempViewSet(ModelViewSet):
    """Opoc检查记录图片"""

    serializer_class = Opoc_InspectionPhotosTempSerializer
    pagination_class = Pagination
    permission_classes = [IsAuthenticated]
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    queryset = Opoc_InspectionPhoto_temp.objects.all()

    @transaction.atomic
    def perform_destroy(self, instance):
        instance.file.delete(save=False)
        instance.delete()
        Response(status=status.HTTP_204_NO_CONTENT)


class Opoc_InspectionRecordsViewSet(ModelViewSet):
    """Opoc检查记录"""

    serializer_class = Opoc_InspectionRecordsSerializer
    pagination_class = Pagination
    permission_classes = [IsAuthenticated]
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    filter_class = Opoc_InspectionRecordsFilter
    search_fields = ['inspection_location','content','problem', 'opoc_record__name','inspector__name']
    select_related_fields = ['opoc_record', 'inspector',]
    ordering_fields = ['id', 'name', 'add_time']

    def get_queryset(self):
        # 根据权限添加额外的查询条件
        if "opoc_view_all" not in self.request.user.permissions:
            queryset = Opoc_InspectionRecord.objects.filter(opoc_record__company=self.request.user.company)
        else:
            queryset = Opoc_InspectionRecord.objects.all()
        return queryset
    #
    # @extend_schema(responses={200: UploadPhotoResponse})
    # @action(detail=False, methods=['post'])
    # def create_inspection_record(request):
    #     record_data = request.data.copy()
    #     photos = record_data.pop('photos', None)
    #
    #     record_serializer = Opoc_InspectionRecordsSerializer(data=record_data)
    #     if not record_serializer.is_valid():
    #         return Response(record_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    #
    #     record = record_serializer.save()
    #
    #     class Opoc_InspectionPhotosSerializer(BaseSerializer):
    #         class Meta:
    #             model = Opoc_InspectionPhoto
    #             fields = '__all__'
    #     if photos:
    #         for photo in photos:
    #             photo_serializer = Opoc_InspectionPhotosSerializer(data={'record': record.id, 'photo': photo})
    #             if photo_serializer.is_valid():
    #                 photo_serializer.save()
    #             else:
    #                 # delete the created InspectionRecord instance if photo is invalid
    #                 record.delete()
    #                 return Response(photo_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    #
    #     return Response(record_serializer.data, status=status.HTTP_201_CREATED)


class Opoc_Labor_service_unitsViewSet(ModelViewSet,ImportMixin):
    """Opoc劳务单位"""
    serializer_class = Opoc_Labor_service_unitsSerializer
    pagination_class = Pagination
    permission_classes = [IsAuthenticated]
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    filter_class = Opoc_Labor_service_unitsFilter
    search_fields = ['company__name', 'name','id']
    select_related_fields = ['company', 'filled_by']
    ordering_fields = ['id', 'name', 'add_time']
    queryset = Labor_service_unit.objects.all()

    @extend_schema(responses={200: DownloadResponse})
    @action(detail=False, methods=['get'])
    def import_template(self, request, *args, **kwargs):
        """导入模板"""

        return self.get_template_response(Labor_service_unitImportExportSerializer)

    @extend_schema(request=UploadRequest, responses={200: UploadResponse})
    @action(detail=False, methods=['post'])
    @transaction.atomic
    def import_data(self, request, *args, **kwargs):
        """导入数据"""

        request_serializer = UploadRequest(data=request.data)
        request_serializer.is_valid(raise_exception=True)
        validated_data = request_serializer.validated_data

        import_serializer = self.load_data(validated_data['file'], Labor_service_unitImportExportSerializer)
        if not import_serializer.is_valid(raise_exception=False):
            raise ValidationError('数据错误')

        labor_service_unit_items = import_serializer.validated_data
        labor_service_unit_set = Labor_service_unit.objects.all()
        create_labor_service_unit_set = []
        update_labor_service_unit_set = []
        for labor_service_unit_item in labor_service_unit_items:
            labor_service_unit_item['filled_by'] = self.user
            labor_service_unit_item['company'] = self.user.company
            for labor_service_unit in labor_service_unit_set:
                if labor_service_unit.name == labor_service_unit_item['name']:
                    update_labor_service_unit_set.append(labor_service_unit)
                    for key, value in labor_service_unit_item.items():
                        setattr(labor_service_unit, key, value)
                    break
            else:
                create_labor_service_unit_set.append(Labor_service_unit(**labor_service_unit_item))
        else:
            try:
                Labor_service_unit.objects.bulk_create(create_labor_service_unit_set)
                Labor_service_unit.objects.bulk_update(update_labor_service_unit_set,
                                              Labor_service_unitImportExportSerializer.Meta.fields)
            except IntegrityError:
                raise ValidationError('有名称重复的劳务单位')

        return Response(status=status.HTTP_200_OK,data={'update_count':10,'creat_count':20})




